<template>
    <div class="login-page">
        <div class="bg">
            <video src="http://chst.vip:8081/crm/media/bg-video.d2d602a9.mp4" loop muted autoplay>
            </video>
        </div>
        <div class="login-container">
            <div class="login-inner">
                <h1 class="title">crm系统</h1>
                <div class="common-login">
                    <el-form ref="loginFormRef" :model="loginForm" status-icon :rules="rules" label-width="120px"
                             class="demo-loginForm">
                        <!-- 用户名 -->
                        <el-form-item label="用户名" prop="username" class="username-form-item">
                            <el-input v-model="loginForm.username" type="input" autocomplete="off" />
                        </el-form-item>
                        <!-- 密码 -->
                        <el-form-item label="密码" prop="password">
                            <el-input v-model="loginForm.password" type="password" autocomplete="off" />
                        </el-form-item>
                        <!-- 验证码 -->
                        <el-form-item label="验证码" prop="captcha" class="captcha">
                            <el-input v-model="loginForm.captcha" @keydown.enter="submitForm(loginFormRef)" maxlength="5" />
                            <span v-loading="captchaLoading" v-html="captcha" @click="getCaptcha"></span>
                        </el-form-item>
                        <el-form-item>
                            <el-button type="primary" @click="submitForm(loginFormRef)">登入</el-button>
                        </el-form-item>
                    </el-form>
                </div>
            </div>
        </div>
    </div>
</template>

<style scoped lang="scss">
/* 修改element-plus样式的思路 */
/* 核心思路:重新编写样式,覆盖默认的element-plus的样式 */
/* 三种方式 */
/* 1. 直接找到当前组件的dom结构中的类名或者id等等,直接编写样式进行覆盖 */
/* 2. 在模块化样式的时候,可以通过深度选择器来完成样式的编写 :deep() */
/* 3. 全局样式,一般会定义一个全局的专门用于覆盖el-plus样式的文件,将样式编写在全局文件中 */

/* 遇到问题: */
/* 
1.检查类名是否正确

2.检查权重

3.是否需要使用深度选择器 */

.login-page {
    .bg {
        video {
            position: fixed;
            left: 0;
            right: 0;
            bottom: 0;
            top: 0;
        }
    }

    .login-container {
        position: fixed;
        z-index: 99;
        // background:#fff;
        min-width: 400px;
        min-height: 400px;
        right: 10%;
        bottom: 15%;
        background-color: rgba(0, 0, 0, .3);
        color: #fff;
        border-radius: 20px;

        .login-inner {
            margin-top: 55px;
            width: 100%;

            .toggle {
                text-align: center;
                // text-decoration: underline;
                margin: 30px 0;

                b {
                    cursor: pointer;
                }
            }

            .title {
                text-align: center;
                color: #fff;
                margin-bottom: 30px;
            }

            :deep(.icon) {
                width: 2em;
                height: 2em;
                margin-right: 5px;
                vertical-align: middle;
            }
        }

    }
}

.captcha {
    display: flex;

    :deep(.el-input) {
        width: 100px;
        border-right: none;

        .el-input__wrapper {
            border-radius: 5px 0 0 5px;
            box-shadow: none;
        }
    }

    span {
        height: 42px;
        background-color: #fff;
        display: inline-block;
        border-left: none;
        border-radius: 0 5px 5px 0;
        width: 60%;
        cursor: pointer;
    }
}

.el-form {
    padding-right: 50px;
    margin-left: -20px;

    :deep(.el-button--primary) {
        height: 40px;
        width: 250px;
        background: linear-gradient(90deg, #1596fb, #002dff);
    }
}

:deep(.el-form-item__label) {
    color: #fff;
    line-height: 40px;
}

:deep(.el-input__inner) {
    height: 40px;
}
</style>

  
<script  setup>
import { reactive, ref, onMounted } from 'vue'

//引入请求验证码的方法
import * as api from "@/api/users"

//引入路由钩子

import { useRouter } from "vue-router"

//引入loading动画
import { ElLoading } from 'element-plus'

//引入store

import useUser from "@/store/users"

//使用store

let userStore = useUser()

//使用useRouter

let router = useRouter()


//创建引用
const loginFormRef = ref()

//表单规则校验的函数

const validateUsername = (rule, value, callback) => {
    // vaule就是对应输入框的输入值
    //callback 如果我们想让验证不通过,就往callback中传递参数,如果通过就不传递参数
    // console.log(value)

    //包含大小写字母 下划线 中划线 数字 3-16为
    let reg = /^[a-zA-Z0-9_-]{3,16}$/

    if (reg.test(value)) {
        callback()
    } else {
        callback('大小写字母,数字,下划线,中划线,3到16位')
    }

}
const validatePassword = (rule, value, callback) => {
    if (value) {
        callback()
    } else {
        callback('输入的密码不能为空')
    }
}

const validateCaptcha = (rule, value, callback) => {
    if (value) {
        callback()
    } else {
        callback('输入的验证码不能为空')
    }
}

//注入到表单中的数据
const loginForm = reactive({
    username: '',
    password: '',
    captcha: '',
})

//声明验证码的响应式变量
const captcha = ref('')

//表单的验证规则对象
const rules = reactive({
    username: [{ validator: validateUsername, trigger: 'blur' }],
    password: [{ validator: validatePassword, trigger: 'blur' }],
    captcha: [{ validator: validateCaptcha, trigger: 'blur' }],
})

//表单提交的时候触发的方法
const submitForm = (formEl) => {
    //formEl就是form组件的引用
    if (!formEl) return

    formEl.validate(async (valid) => {
        //用组件的时候 可以适当忽略逻辑的实现细节,只需要知道关键变量的使用就行了
        if (valid) {
            //打开加载动画
            const loading = ElLoading.service({
                lock: true,
                text: '正在登入...',
                background: 'rgba(0, 0, 0, 0.7)',
            })

            //表单校验通过
            try {

                //发起请求 验证验证码
                let captchaVerify = await validateCaptchaRemote(loginForm.captcha)
                //验证码通过之后发起登入请求
                if (captchaVerify) {
                    //获取登入的结果
                    let res = await api.loginApi(loginForm.username, loginForm.password)

                    // console.log(res)
                    let { permission, token, userInfo } = res.data;

                    //将permission和userInfo存到userStore中

                    userStore.permission.value = permission;

                    userStore.userInfo.value = userInfo;

                    //将token存到sessionStorage
                    sessionStorage.setItem('tk', token)

                    //跳转到首页

                    router.push('/')

                }

                //关闭加载动画

                loading.close()

            } catch (e) {
                console.log(e)
                //关闭加载动画
                loading.close()
            }

        } else {

            //表单校验失败,啥也不干,return false就行了

            return false
        }
    })
}

// ✂️✂️✂️✂️✂️✂️✂️✂️✂️✂️✂️华丽的分割线✂️✂️✂️✂️✂️✂️✂️✂️✂️✂️✂️✂️

//控制验证码加载动画的变量

const captchaLoading = ref(false)

//获取验证码的方法

const getCaptcha = async () => {
    //打开验证码加载动画
    captchaLoading.value = true;
    try {
        //发起请求
        const res = await api.getCaptchaApi()
        // console.log(res)
        //给表单对象赋值
        captcha.value = res.data.img
        //关闭验证码加载动画
        captchaLoading.value = false
    } catch (e) {
        console.log(e)

        captchaLoading.value = false
    }
}

//校验验证码

const validateCaptchaRemote = async (captcha) => {
    //将captcha通通转换成小写
    typeof captcha === 'string' && captcha.toLowerCase()
    try {
        //发起请求
        const res = await api.verifyCaptchaApi(captcha)

        //res.data.state为true表示校验通过
        return res.data.state

    } catch (e) {
        console.log(e)
        return false
    }
}

//组件挂载之后的钩子

onMounted(() => {
    //获取验证码
    getCaptcha()
})

</script>

  